package com.example.sandbox.controller.order.pay58;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.example.sandbox.controller.order.abstractController.AbstractTransferOrderController;
import com.example.sandbox.controller.order.model.Brazil58TransferOrderRequest;
import com.example.sandbox.controller.order.model.DownStreamConstant;
import com.example.sandbox.controller.order.model.TransferOrderRQ;
import com.example.sandbox.controller.order.model.TransferOrderRS;
import com.example.sandbox.dto.ApiRes;
import com.example.sandbox.dto.CS;
import com.example.sandbox.dto.Enum.ApiCodeEnum;
import com.example.sandbox.dto.Enum.Currency;
import com.example.sandbox.dto.Enum.Order58payStatus;
import com.example.sandbox.dto.MchRedisContext;
import com.example.sandbox.dto.domain.TransferOrder;
import com.example.sandbox.helper.BizException;
import com.example.sandbox.helper.MchAndSignCheckHelper;
import com.example.sandbox.util.AmountUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.Random;

/**
 * @Author Lierbao
 * @Date 2024/6/14 11:50 下游代付接口
 */

@Slf4j
@RestController
@Api(tags = "巴西代付接口")
public class Brazil58TransferOrderController {
    private static final Random RANDOM = new Random();
    @Resource
    private MchAndSignCheckHelper mchAndSignCheckHelper;
    @Autowired
    private AbstractTransferOrderController abstractTransferOrderController;
    @PostMapping("/gateway/v1/pay/brazil/cashOut/submit")
    @ResponseBody
    @ApiOperation("巴西IfCode代付")
    public ApiRes transferOrderIfCode(@RequestBody @Valid Brazil58TransferOrderRequest request,
                                      HttpServletRequest httpRequest) {
        long startTime = System.currentTimeMillis();
        log.info("巴西IfCode代付接口入参 [{}]", JSON.toJSONString(request));
        // 代付入参校验
        if (StringUtils.isBlank(request.getAccountType())) {
            log.error("accountType must not be blank [{}]-[{}]", request.getMerchantNo(), request.getClientRequestId());
            throw new BizException("accountType must not be blank");
        }
        if (StringUtils.isBlank(request.getTaxId())) {
            log.error("taxId must not be blank [{}]-[{}]", request.getMerchantNo(), request.getClientRequestId());
            throw new BizException("taxId must not be blank");
        }
        // 验签
        // MchApp mchApp = mchAndSignCheckHelper.mchAndSignAndIPCheck(request, httpRequest, request.getNotifyUrl());
        MchRedisContext mchRedisContext =
                mchAndSignCheckHelper.mch58AndSignAndIPCheckRedis(request, httpRequest, request.getNotifyUrl());

        log.info("接口代付验签 耗时:[{}]", System.currentTimeMillis() - startTime);
        // 装配请求参数
        TransferOrderRQ transferOrderRQ = new TransferOrderRQ();
        transferOrderRQ.setOrderId(gen58TransferOrderId());
        transferOrderRQ.setMchNo(request.getMerchantNo());
        transferOrderRQ.setAppId(mchRedisContext.getAppId());
        transferOrderRQ.setMchOrderNo(request.getClientRequestId());
        transferOrderRQ.setIfCode(CS.IF_CODE.BRAZIL_PAY);
        transferOrderRQ.setEntryType(TransferOrder.ENTRY_PIXCRED_CASH);
        transferOrderRQ
                .setAmount(Long.parseLong(AmountUtil.convertDollar2Cent(request.getAmount(), Currency.BRL.getCurrency())));
        transferOrderRQ.setCurrency(Currency.BRL.getCurrency());
        transferOrderRQ.setAccountNo(request.getAccountNo());
        transferOrderRQ.setBankName(null);
        transferOrderRQ.setClientIp("0.0.0.1");
        transferOrderRQ.setTransferDesc(request.getRemittanceInformation());
        transferOrderRQ.setNotifyUrl(request.getNotifyUrl());

        JSONObject extParams = new JSONObject();
        extParams.put("identityType", request.getAccountType());
        extParams.put("identityNo", request.getTaxId());
        // FIXME 以下参数暂填固定值
        if (StringUtils.isNotBlank(request.getAccountType()) && "cnpj".equals(request.getAccountType().trim().toLowerCase())) {
            throw new BizException("cnpj is not support");
        }
        transferOrderRQ.setChannelExtra(extParams.toJSONString());

        transferOrderRQ.setExtParam(null);
        transferOrderRQ.setReqTime(request.getReqTime() + "");
        transferOrderRQ.setVersion(DownStreamConstant.VERSION);
        transferOrderRQ.setSign(request.getSign());
        transferOrderRQ.setSignType("MD5");
        log.info("构造代付参数 耗时：[{}]", System.currentTimeMillis() - startTime);
        ApiRes apiRes = abstractTransferOrderController.transferOrderAsyncRequestUpStream(transferOrderRQ, mchRedisContext);
        if (null == apiRes) {
            return apiRes;
        }
        // 业务错误直接返回
        if (!Objects.isNull(apiRes.getCode()) && ApiCodeEnum.SUCCESS.getCode() != apiRes.getCode()) {
            log.info("[{}]支付下单链路耗时: [{}]ms", request.getClientRequestId(), System.currentTimeMillis() - startTime);
            return apiRes;
        }

        TransferOrderRS data = (TransferOrderRS) apiRes.getData();
        if (null == data) {
            return apiRes;
        }
        // 序列化对象并解析回 JSON 对象
        String jsonString = JSON.toJSONString(data, SerializerFeature.WriteMapNullValue);
        JSONObject jsonRetMsg = JSON.parseObject(jsonString);
        jsonRetMsg.remove("channelRetMsg");
        jsonRetMsg.put("orderState", Order58payStatus.getValueByKey(data.getState()));
        ApiRes<Object> ok = ApiRes.ok(jsonRetMsg);
        ok.setSign(apiRes.getSign());
        // stopWatch.stop();
        log.info("[{}]支付下单链路耗时: [{}]ms", request.getClientRequestId(), System.currentTimeMillis() - startTime);


        return apiRes;
    }
    public static String gen58TransferOrderId() {

        // 生成时间戳
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());

        // 生成随机数部分
        long randomPart = RANDOM.nextInt(100000000); // 生成一个9位随机数

        return String.format("%s%s%09d", "O", timestamp, randomPart);
    }
}
